//
//  ForgotPasswordViewModel.swift
//  User
//
//  Created by ET|冰琳 on 2017/1/12.
//  Copyright © 2017年 IB. All rights reserved.
//

import Foundation
import ReactiveCocoa
import ReactiveSwift

public enum ForgotPasswordError: Error {
    case phoneInvalide
    case codeInvalide
    case passwordInvalide
    case error(msg: String)
}

open class ForgotPasswordViewModel<Service: ForgotPasswordService>: NSObject {
   
    open var phone = MutableProperty<String?>(nil)
    open var code  = MutableProperty<String?>(nil)
    open var password = MutableProperty<String?>(nil)
    
    open var phoneValide = MutableProperty(false)
    open var codeValide = MutableProperty(false)
    open var passwordValide = MutableProperty(false)
    
    open var phoneValidator: Validator?
    open var codeValidator: Validator?
    open var passwordValidator: Validator?
    
    private var service: Service
    
    open var commit: Action<(), Service.ForgotPasswordResult, ForgotPasswordError>!
    open var getCode: Action<(), Service.ForgotPasswordCodeResult, ForgotPasswordError>!
    
    public init(service: Service) {
        self.service = service
        super.init()
    
        self.commit = Action({ (_) in
            return self.commitForgot()
        })
        
        self.getCode = Action({ (_) in
            return self.fetchCode()
        })
    }
    
    /// - private
    private func calculateValide() {
        
        phoneValide <~ phone.signal.map({
            let validator = self.phoneValidator ?? PhoneValidator()
            return validator.validate(txt: $0)
        })
        
        codeValide <~ code.signal.map({
            let validator = self.codeValidator ?? DefaultValidator()
            return validator.validate(txt: $0)
        })
        
        passwordValide <~ code.signal.map({
            let validator = self.passwordValidator ?? DefaultValidator()
            return validator.validate(txt: $0)
        })
    }
    
    private func fetchCode() -> SignalProducer<Service.ForgotPasswordCodeResult, ForgotPasswordError> {
        
        guard self.phoneValide.value else {
            return SignalProducer(error: .phoneInvalide)
        }
        
        return self.service.getForgetPasswordCodeWith(phone: self.phone.value)
            .flatMapError({ (error) -> SignalProducer<Service.ForgotPasswordCodeResult, ForgotPasswordError> in
                return SignalProducer(error: .error(msg: error.localizedDescription))
            })
    }
    
    private func commitForgot() -> SignalProducer<Service.ForgotPasswordResult, ForgotPasswordError>{
      
        return self.service.resetPasswordWith(phone: self.phone.value, code: self.code.value, newpwd: self.password.value)
            .flatMapError({ (error) -> SignalProducer<Service.ForgotPasswordResult, ForgotPasswordError> in
                return SignalProducer(error: .error(msg: error.localizedDescription))
            })
    }
}
